Global parameters for modeling

Exploratory Plots

Some exploratory plots of un-modeled gene counts.

Before you do any statistical analysis, it’s important to know what your data looks like. This is important for two main reasons:

We’re going to look at the raw (and mostly raw) gene count data in a few ways.

Heatmaps

In all the following heatmaps, samples or genes are clustered by Euclidean distance of rlog-transformed gene counts (this removed the dependence of variance on mean, and flattens out the variance across the data set, which makes the heatmaps a little easier to read). Transformed counts were not used for the DESeq2 analysis.

Individuals clustered by overall expression

This is a heatmap clustering individuals by their expression levels for all genes. Essentially, this is a correlation plot. Each individual is perfectly correlated with itself (the dark blue diagonal). This plot shows two big groups. One that is all cannibals (on the left), one that is all non-cannibals (on the right). Families tend to cluster within feeding strategies/groups.

Individuals by Top 500 genes heatmap

Here we’re using the same transformed counts to look at overall expression, however I’ve filtered out all but the top 500 most highly expressed genes (on average, across all individuals). Here, I’m only clustering by individuals on the x-axis, where the x-axis is individuals, but the y-axis is transcripts. Here, we can see that in the 500 most expressed genes, there are very few that have highly varying expression across samples. However, in these 500 genes, we can better cluster non-cannibals vs cannibals. There is still pretty good clustering of families within feeding strategy.

Individuals clustered by top 500 gene expression

This plot is analogous to the first heatmap, in that I’m now showing a correlation matrix, however this is using just the top 500 most expressed genes rather than all of them. Clustering with the top 500 genes is giving us three big expression groups: cannibals, non-cannibals and a mix.

PCA for overall expression

Here, instead of looking at correlations, we’re doing a PCA. This takes the entire (transformed) count table and rotates it to find the set of orthagonal axes with the most variation. Here I’m always plotting PC1 vs PC2 (the most variable and second most variable axis). I’m coloring points by either family, feeding strategy, or both. Since PCA looks for the axis in the data with the most variation, what this will do is push dis-similar samples away from each other in the plot. In effect, we can see whether there are already clusters in the data from variables that we’re not interested in and want to model out.

In these plots, for instance, you can see on the top left that the Mc samples are pretty different from all the others, and that family effect might be part of why we’re getting three clusters in the last heatmap. If we don’t account for family in the DESeq model, we’ll probably get the wrong genes.

In the top right plot, you can see that non-cannibals and cannibals actually are pretty easily distinguishable just by overall gene expression, which is good. Once we account for family, we should have a fairly reliable gene list.

However, if there are other meta-data factors that differ between samples we should add them into this plot and check for those before going forward. This would be things like batch effects, lane effects, sample extraction differences, etc.

LS0tCnRpdGxlOiAiREVhbmFseXNpc19rZmlzaF9vc21vdGljIgphdXRob3I6ICJMaXNhIEpvaG5zb24iCmRhdGU6ICdgciBTeXMuRGF0ZSgpYCcKb3V0cHV0OgogIGh0bWxfZG9jdW1lbnQ6CiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUKICAgIGNvbGxhcHNlZDogbm8KICAgIGRmX3ByaW50OiBwYWdlZAogICAgbnVtYmVyX3NlY3Rpb25zOiB5ZXMKICAgIHRoZW1lOiBjZXJ1bGVhbgogICAgdG9jOiB5ZXMKICAgIHRvY19kZXB0aDogNQogICAgdG9jX2Zsb2F0OiB5ZXMKICBodG1sX25vdGVib29rOgogICAgdG9jOiB5ZXMKICAgIHRvY19kZXB0aDogNQotLS0KCmBgYHtyIEdsb2JhbFZhcmlhYmxlc30KCiNTZXR0aW5nIGEgcmVhc29uYWJsZSBwLXZhbHVlIHRocmVzaG9sZCB0byBiZSB1c2VkIHRocm91Z2hvdXQKCnBfY3V0b2ZmIDwtIDAuMDUKCnBfY3V0b2ZmX25ldyA8LSAwLjA1Cgprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IEZBTFNFLCBtZXNzYWdlID0gRkFMU0UsIHdhcm5pbmcgPSBGQUxTRSkKCkZDX2N1dG9mZl9vcmlnaW5hbCA8LSAwCgpGQ19jdXRvZmZfbmV3IDwtIDEKCgpgYGAKCgojR2xvYmFsIHBhcmFtZXRlcnMgZm9yIG1vZGVsaW5nCgoKCmBgYHtyIExvYWRQYWNrYWdlcywgcmVzdWx0cz0naGlkZScsIGluY2x1ZGU9RkFMU0V9CgojIEluc3RhbGwgZnVuY3Rpb24gZm9yIHBhY2thZ2VzICAgIApwYWNrYWdlczwtZnVuY3Rpb24oeCl7CiAgeDwtYXMuY2hhcmFjdGVyKG1hdGNoLmNhbGwoKVtbMl1dKQogIGlmICghcmVxdWlyZSh4LGNoYXJhY3Rlci5vbmx5PVRSVUUpKXsKICAgIGluc3RhbGwucGFja2FnZXMocGtncz14LHJlcG9zPSJodHRwOi8vY3Jhbi5yLXByb2plY3Qub3JnIikKICAgIHJlcXVpcmUoeCxjaGFyYWN0ZXIub25seT1UUlVFKQogIH0KfQoKYmlvY29uZHVjdG9ycyA8LSBmdW5jdGlvbih4KXsKICAgIHg8LSBhcy5jaGFyYWN0ZXIobWF0Y2guY2FsbCgpW1syXV0pCiAgICBpZiAoIXJlcXVpcmUoeCwgY2hhcmFjdGVyLm9ubHkgPSBUUlVFKSl7CiAgICAgIHNvdXJjZSgiaHR0cHM6Ly9iaW9jb25kdWN0b3Iub3JnL2Jpb2NMaXRlLlIiKQogICAgICBiaW9jTGl0ZShwa2dzPXgpCiAgICAgIHJlcXVpcmUoeCwgY2hhcmFjdGVyLm9ubHkgPSBUUlVFKQogICAgfQp9CgpwYWNrYWdlcyhNQVNTKQpwYWNrYWdlcyhnZ3Bsb3QyKQpwYWNrYWdlcyhndG9vbHMpCnBhY2thZ2VzKHBoZWF0bWFwKQpwYWNrYWdlcyhjb3dwbG90KQpwYWNrYWdlcyhSQ29sb3JCcmV3ZXIpCnBhY2thZ2VzKGRwbHlyKQpwYWNrYWdlcyh0aWR5cikKcGFja2FnZXMoZ2dyZXBlbCkKYmlvY29uZHVjdG9ycyhERVNlcTIpCmJpb2NvbmR1Y3RvcnMobGltbWEpCmJpb2NvbmR1Y3RvcnMoJ2VkZ2VSJykKcGFja2FnZXMoZ3Bsb3RzKQpwYWNrYWdlcyhsYXR0aWNlKQoKc2Vzc2lvbkluZm8oKQoKYGBgCgoKYGBge3IgbG9hZGZpbGVzLCByZXN1bHRzPSdoaWRlJywgaW5jbHVkZT1GQUxTRX0KCiMgVGhpcyBpcyB0aGUgY291bnRzIHdpdGggRXhwZXJpbWVudGFsIERlc2lnbiBJbmZvIGluIHRoZSBsYXN0IDUgcm93cwoKaWYoIWZpbGUuZXhpc3RzKCcuLi8uLi8uLi9FbnNlbWJsX3NwZWNpZXNfY291bnRzX2Rlc2lnbmZhY3RvcnMuY3N2JykpewogIGRvd25sb2FkLmZpbGUoImh0dHBzOi8vb3NmLmlvLzd2cDM4L2Rvd25sb2FkIiwnRW5zZW1ibF9zcGVjaWVzX2NvdW50c19kZXNpZ25mYWN0b3JzLmNzdicpCn0KaWYoIWZpbGUuZXhpc3RzKCcuLi8uLi8uLi9ub256ZXJvX2NsYWRlX3BoeXNpb2xvZ3lfY291bnRzX2Rlc2lnbi5jc3YnKSl7CiAgZG93bmxvYWQuZmlsZSgiaHR0cHM6Ly9vc2YuaW8vYmU3bnkvZG93bmxvYWQiLCdub256ZXJvX2NsYWRlX3BoeXNpb2xvZ3lfY291bnRzX2Rlc2lnbi5jc3YnKQp9CmlmKCFmaWxlLmV4aXN0cygnLi4vLi4vLi4vZ3JlYXRlcjVjb3VudHNfY2xhZGVfcGh5c2lvbG9neV9jb3VudHNfZGVzaWduLmNzdicpKXsKICBkb3dubG9hZC5maWxlKCJodHRwczovL29zZi5pby9iZTdueS9kb3dubG9hZCIsJ2dyZWF0ZXI1Y291bnRzX2NsYWRlX3BoeXNpb2xvZ3lfY291bnRzX2Rlc2lnbi5jc3YnKQp9CgojY291bnRzX2Rlc2lnbiA8LSByZWFkLmNzdigiRW5zZW1ibF9zcGVjaWVzX2NvdW50c19kZXNpZ25mYWN0b3JzLmNzdiIsc3RyaW5nc0FzRmFjdG9ycyA9IFRSVUUpCmNvdW50c19kZXNpZ24gPC0gcmVhZC5jc3YoIi4uLy4uLy4uL25vbnplcm9fY2xhZGVfcGh5c2lvbG9neV9jb3VudHNfZGVzaWduLmNzdiIsc3RyaW5nc0FzRmFjdG9ycyA9IFRSVUUpCgoKYGBgCgoKYGBge3IgZGVzaWduaW5mbywgaW5jbHVkZT1GQUxTRX0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojIEZvcm1hdCBkZXNpZ24gYW5kIGNvdW50cyBtYXRyaXgKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKZGVzaWduIDwtIGNvdW50c19kZXNpZ25bY291bnRzX2Rlc2lnbiRFbnNlbWJsID09ICdFbXB0eScsXQojZGVzaWduJHR5cGUgPC0gYygic3BlY2llcyIsIm5hdGl2ZV9zYWxpbml0eSIsImNsYWRlIiwiZ3JvdXAiLCJjb25kaXRpb24iKQpkcm9wcyA8LSBjKCJYIiwiRW5zZW1ibCIsCiAgICAgICAgICAgIkZfemVicmludXNfQldfMS5xdWFudCIsIkZfemVicmludXNfQldfMi5xdWFudCIsCiAgICAgICAgICAgIkZfemVicmludXNfRldfMS5xdWFudCIsIkZfemVicmludXNfRldfMi5xdWFudCIsCiAgICAgICAgICAgIkZfbm90dGlfRldfMS5xdWFudCIsIkZfbm90dGlfRldfMi5xdWFudCIsCiAgICAgICAgICAgIkZfc2NpYWRpY3VzX0JXXzEucXVhbnQiLCJGX3NjaWFkaWN1c19GV18xLnF1YW50IiwiRl9zY2lhZGljdXNfRldfMi5xdWFudCIpCnRyYW5zZmVyX2Ryb3BzIDwtIGMoIkZfc2NpYWRpY3VzX3RyYW5zZmVyXzEucXVhbnQiLCJGX3JhdGhidW5pX3RyYW5zZmVyXzEucXVhbnQiLCJGX3JhdGhidW5pX3RyYW5zZmVyXzIucXVhbnQiLCJGX3JhdGhidW5pX3RyYW5zZmVyXzMucXVhbnQiLAogICAgICAgICAgICAgICAgICAgICJGX2dyYW5kaXNfdHJhbnNmZXJfMS5xdWFudCIsIkZfZ3JhbmRpc190cmFuc2Zlcl8yLnF1YW50IiwiRl9ncmFuZGlzX3RyYW5zZmVyXzMucXVhbnQiLAogICAgICAgICAgICAgICAgICAgICJGX25vdGF0dXNfdHJhbnNmZXJfMS5xdWFudCIsIkZfbm90YXR1c190cmFuc2Zlcl8yLnF1YW50IiwiRl9ub3RhdHVzX3RyYW5zZmVyXzMucXVhbnQiLAogICAgICAgICAgICAgICAgICAgICJGX3BhcnZhcGluaXNfdHJhbnNmZXJfMS5xdWFudCIsIkZfcGFydmFwaW5pc190cmFuc2Zlcl8yLnF1YW50IiwKICAgICAgICAgICAgICAgICAgICAiTF9nb29kZWlfdHJhbnNmZXJfMS5xdWFudCIsIkxfZ29vZGVpX3RyYW5zZmVyXzIucXVhbnQiLCJMX2dvb2RlaV90cmFuc2Zlcl8zLnF1YW50IiwKICAgICAgICAgICAgICAgICAgICAiRl9vbGl2YWNlb3VzX3RyYW5zZmVyXzEucXVhbnQiLCJGX29saXZhY2VvdXNfdHJhbnNmZXJfMi5xdWFudCIsCiAgICAgICAgICAgICAgICAgICAgIkxfcGFydmFfdHJhbnNmZXJfMS5xdWFudCIsIkxfcGFydmFfdHJhbnNmZXJfMi5xdWFudCIsIkxfcGFydmFfdHJhbnNmZXJfMy5xdWFudCIsCiAgICAgICAgICAgICAgICAgICAgIkZfaGV0ZXJvY2xpdHVzTURQUF90cmFuc2Zlcl8xLnF1YW50IiwiRl9oZXRlcm9jbGl0dXNNRFBQX3RyYW5zZmVyXzIucXVhbnQiLCJGX2hldGVyb2NsaXR1c01EUFBfdHJhbnNmZXJfMy5xdWFudCIsCiAgICAgICAgICAgICAgICAgICAgIkZfc2ltaWxpc190cmFuc2Zlcl8xLnF1YW50IiwiRl9zaW1pbGlzX3RyYW5zZmVyXzIucXVhbnQiLCJGX3NpbWlsaXNfdHJhbnNmZXJfMy5xdWFudCIsCiAgICAgICAgICAgICAgICAgICAgIkZfZGlhcGhhbnVzX3RyYW5zZmVyXzEucXVhbnQiLCJGX2RpYXBoYW51c190cmFuc2Zlcl8yLnF1YW50IiwKICAgICAgICAgICAgICAgICAgICAiRl9jaHJ5c290dXNfdHJhbnNmZXJfMS5xdWFudCIsIkZfY2hyeXNvdHVzX3RyYW5zZmVyXzIucXVhbnQiLAogICAgICAgICAgICAgICAgICAgICJBX3hlbmljYV90cmFuc2Zlcl8xLnF1YW50IiwiQV94ZW5pY2FfdHJhbnNmZXJfMi5xdWFudCIsIkFfeGVuaWNhX3RyYW5zZmVyXzMucXVhbnQiICwKICAgICAgICAgICAgICAgICAgICAiRl9jYXRhbmF0dXNfdHJhbnNmZXJfMS5xdWFudCIsIkZfY2F0YW5hdHVzX3RyYW5zZmVyXzIucXVhbnQiLAogICAgICAgICAgICAgICAgICAgICJGX2hldGVyb2NsaXR1c01EUExfdHJhbnNmZXJfMS5xdWFudCIsIkZfaGV0ZXJvY2xpdHVzTURQTF90cmFuc2Zlcl8yLnF1YW50IiwiRl9oZXRlcm9jbGl0dXNNRFBMX3RyYW5zZmVyXzMucXVhbnQiKQpjb3VudHM8LWNvdW50c19kZXNpZ25bIWNvdW50c19kZXNpZ24kRW5zZW1ibCA9PSAnRW1wdHknLF0Kcm93bmFtZXMoY291bnRzKTwtY291bnRzJEVuc2VtYmwKZGVzaWduIDwtIGRlc2lnblsgLCAhKG5hbWVzKGRlc2lnbikgJWluJSBkcm9wcyldCmNvdW50cyA8LSBjb3VudHNbICwgIShuYW1lcyhjb3VudHMpICVpbiUgZHJvcHMpXQpkZXNpZ24gPC0gZGVzaWduWyAsICEobmFtZXMoZGVzaWduKSAlaW4lIHRyYW5zZmVyX2Ryb3BzKV0KY291bnRzIDwtIGNvdW50c1sgLCAhKG5hbWVzKGNvdW50cykgJWluJSB0cmFuc2Zlcl9kcm9wcyldCmRpbShkZXNpZ24pCiNbMV0gIDUgODEKZGltKGNvdW50cykKI1sxXSAzMDQ2NiAgICA4MQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tCiMgZGVzaWduIGNhdGVvZ29yaWVzCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnNwZWNpZXM8LWFzLmNoYXJhY3Rlcih1bmxpc3QoZGVzaWduWzEsXSkpCnBoeXNpb2xvZ3k8LWFzLmNoYXJhY3Rlcih1bmxpc3QoZGVzaWduWzIsXSkpCmNsYWRlPC1hcy5jaGFyYWN0ZXIodW5saXN0KGRlc2lnblszLF0pKQpjb25kaXRpb248LWFzLmNoYXJhY3Rlcih1bmxpc3QoZGVzaWduWzUsXSkpCmNvbmRpdGlvbl9waHlzaW9sb2d5PC1hcy52ZWN0b3IocGFzdGUoY29uZGl0aW9uLHBoeXNpb2xvZ3ksc2VwPSIuIikpCmNvbHM8LWNvbG5hbWVzKGNvdW50cykKRXhwRGVzaWduIDwtIGRhdGEuZnJhbWUocm93Lm5hbWVzPWNvbHMsCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbmRpdGlvbj1jb25kaXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgIHBoeXNpb2xvZ3kgPSBwaHlzaW9sb2d5LAogICAgICAgICAgICAgICAgICAgICAgICBjbGFkZSA9IGNsYWRlLAogICAgICAgICAgICAgICAgICAgICAgICBzcGVjaWVzID0gc3BlY2llcywKICAgICAgICAgICAgICAgICAgICAgICAgc2FtcGxlPWNvbHMpCkV4cERlc2lnbgpkZXNpZ24gPSBtb2RlbC5tYXRyaXgoIH4gcGh5c2lvbG9neSArIGNvbmRpdGlvbiArIHBoeXNpb2xvZ3k6Y29uZGl0aW9uLCBFeHBEZXNpZ24pCgpjb2xuYW1lcyhkZXNpZ24pCiMgY2hlY2sgcmFuayBvZiBtYXRyaXgKTWF0cml4OjpyYW5rTWF0cml4KCBkZXNpZ24gKQpkaW0oZGVzaWduKQpgYGAKCgpgYGB7ciBub3JtLCByZXN1bHRzPSdoaWRlJywgaW5jbHVkZT1GQUxTRX0KY291bnRzX3JvdW5kIDwtIHJvdW5kKGRhdGEubWF0cml4KGNvdW50cyksIGRpZ2l0cz0wKQojY291bnRzX3JvdW5kIDwtIGhlYWQoY291bnRzX3JvdW5kLCBuID0gMTkwMDApCmRpbShjb3VudHNfcm91bmQpCiNwbG90KGNvbFN1bXModChjb3VudHNfcm91bmQpKSApCmxjcG0yIDwtIGNwbShjb3VudHNfcm91bmQsIGxvZyA9IFRSVUUpCiNib3hwbG90KGxjcG0yLCBsYXMgPSAyLCBtYWluID0gIkJlZm9yZSBERVNlcTIgTm9ybWFsaXphdGlvbiIpCgojIHRyYW5zZm9ybSB3aXRoIERFU2VxIHRvIHN0YWJpbGl6ZSB2YXJpYW5jZQoKZGRzIDwtIERFU2VxRGF0YVNldEZyb21NYXRyaXgoY291bnREYXRhID0gY291bnRzX3JvdW5kLGNvbERhdGEgPSBFeHBEZXNpZ24sZGVzaWduID0gZGVzaWduKQpkZHMgPC0gZXN0aW1hdGVTaXplRmFjdG9ycyhkZHMpCmRkcyA8LSBlc3RpbWF0ZURpc3BlcnNpb25zKGRkcykKZGRzJHNpemVGYWN0b3IKbmMgPC0gY291bnRzKGRkcywgbm9ybWFsaXplZD1UUlVFKQojd3JpdGUuY3N2KG5jLCAiLi4vLi4vLi4vbm9ybWNvdW50cy5jc3YiKQpjb3VudHM8LW5jCiNwbG90KGNvbFN1bXModChjb3VudHMpKSApCgpjcG0gPC0gY3BtKGNvdW50cykKbGNwbSA8LSBjcG0oY291bnRzLCBsb2cgPSBUUlVFKQojcGxvdChjb2xTdW1zKHQobGNwbSkpICkKI2JveHBsb3QobGNwbSwgbGFzID0gMiwgbWFpbiA9ICJBZnRlciBERVNlcTIgTm9ybWFsaXphdGlvbiIpCmBgYAoKCiMgRXhwbG9yYXRvcnkgUGxvdHMKClNvbWUgZXhwbG9yYXRvcnkgcGxvdHMgb2YgdW4tbW9kZWxlZCBnZW5lIGNvdW50cy4KCkJlZm9yZSB5b3UgZG8gYW55IHN0YXRpc3RpY2FsIGFuYWx5c2lzLCBpdCdzIGltcG9ydGFudCB0byBrbm93IHdoYXQgeW91ciBkYXRhIGxvb2tzIGxpa2UuIFRoaXMgaXMgaW1wb3J0YW50IGZvciB0d28gbWFpbiByZWFzb25zOgoKICAtIEl0IGNhbiBoZWxwIHlvdSBmaW5kIGVycm9ycyB0aGF0IHdpbGwgZWZmZWN0IHlvdXIgZG93bnN0cmVhbSBhbmFseXNpcwogIC0gSXQgY2FuIGhlbHAgeW91IHRvIGNob29zZSBhbiBhcHByb3ByaWF0ZSBhbmFseXNpcyBmb3IgeW91ciBkYXRhCgpXZSdyZSBnb2luZyB0byBsb29rIGF0IHRoZSByYXcgKGFuZCBtb3N0bHkgcmF3KSBnZW5lIGNvdW50IGRhdGEgaW4gYSBmZXcgd2F5cy4KCiMjIEhlYXRtYXBzCgoKSW4gYWxsIHRoZSBmb2xsb3dpbmcgaGVhdG1hcHMsIHNhbXBsZXMgb3IgZ2VuZXMgYXJlIGNsdXN0ZXJlZCBieSBFdWNsaWRlYW4gZGlzdGFuY2Ugb2YgcmxvZy10cmFuc2Zvcm1lZCBnZW5lIGNvdW50cyAodGhpcyByZW1vdmVkIHRoZSBkZXBlbmRlbmNlIG9mIHZhcmlhbmNlIG9uIG1lYW4sIGFuZCBmbGF0dGVucyBvdXQgdGhlIHZhcmlhbmNlIGFjcm9zcyB0aGUgZGF0YSBzZXQsIHdoaWNoIG1ha2VzIHRoZSBoZWF0bWFwcyBhIGxpdHRsZSBlYXNpZXIgdG8gcmVhZCkuIFRyYW5zZm9ybWVkIGNvdW50cyB3ZXJlICpub3QqIHVzZWQgZm9yIHRoZSBERVNlcTIgYW5hbHlzaXMuCgojIyMgSW5kaXZpZHVhbHMgY2x1c3RlcmVkIGJ5IG92ZXJhbGwgZXhwcmVzc2lvbgoKVGhpcyBpcyBhIGhlYXRtYXAgY2x1c3RlcmluZyBpbmRpdmlkdWFscyBieSB0aGVpciBleHByZXNzaW9uIGxldmVscyBmb3IgYWxsIGdlbmVzLiBFc3NlbnRpYWxseSwgdGhpcyBpcyBhIGNvcnJlbGF0aW9uIHBsb3QuIEVhY2ggaW5kaXZpZHVhbCBpcyBwZXJmZWN0bHkgY29ycmVsYXRlZCB3aXRoIGl0c2VsZiAodGhlIGRhcmsgYmx1ZSBkaWFnb25hbCkuIFRoaXMgcGxvdCBzaG93cyB0d28gYmlnIGdyb3Vwcy4gT25lIHRoYXQgaXMgYWxsIGNhbm5pYmFscyAob24gdGhlIGxlZnQpLCBvbmUgdGhhdCBpcyBhbGwgbm9uLWNhbm5pYmFscyAob24gdGhlIHJpZ2h0KS4gRmFtaWxpZXMgdGVuZCB0byBjbHVzdGVyIHdpdGhpbiBmZWVkaW5nIHN0cmF0ZWdpZXMvZ3JvdXBzLgoKYGBge3IgUGxhaW5IZWF0bWFwLCBmaWcua2VlcD0ibGFzdCIsIGZpZy53aWR0aD0xMSwgZmlnLnBhdGg9J2ZpZ3VyZXMvJywgZGV2PWMoJ3BuZycsICdwZGYnKX0KI0EgdXNlZnVsIGZpcnN0IHN0ZXAgaW4gYW4gUk5BLXNlcSBhbmFseXNpcyBpcyBvZnRlbiB0byBhc3Nlc3Mgb3ZlcmFsbCBzaW1pbGFyaXR5IGJldHdlZW4gc2FtcGxlczogV2hpY2ggc2FtcGxlcyBhcmUgc2ltaWxhciB0byBlYWNoIG90aGVyLCB3aGljaCBhcmUgZGlmZmVyZW50PyBEb2VzIHRoaXMgZml0IHRvIHRoZSBleHBlY3RhdGlvbiBmcm9tIHRoZSBleHBlcmltZW504oCZcyBkZXNpZ24/IFdlIHVzZSB0aGUgUiBmdW5jdGlvbiBkaXN0IHRvIGNhbGN1bGF0ZSB0aGUgRXVjbGlkZWFuIGRpc3RhbmNlIGJldHdlZW4gc2FtcGxlcy4gVG8gZW5zdXJlIHdlIGhhdmUgYSByb3VnaGx5IGVxdWFsIGNvbnRyaWJ1dGlvbiBmcm9tIGFsbCBnZW5lcywgd2UgdXNlIGl0IG9uIHRoZSBybG9nLXRyYW5zZm9ybWVkIGRhdGEuIFdlIG5lZWQgdG8gdHJhbnNwb3NlIHRoZSBtYXRyaXggb2YgdmFsdWVzIHVzaW5nIHQsIGJlY2F1c2UgdGhlIGRpc3QgZnVuY3Rpb24gZXhwZWN0cyB0aGUgZGlmZmVyZW50IHNhbXBsZXMgdG8gYmUgcm93cyBvZiBpdHMgYXJndW1lbnQsIGFuZCBkaWZmZXJlbnQgZGltZW5zaW9ucyAoaGVyZSwgZ2VuZXMpIHRvIGJlIGNvbHVtbnMuIAojKipOb3RlIHRoYXQgdGhlIHR3byB0cmFuc2Zvcm1hdGlvbnMgb2ZmZXJlZCBieSBERVNlcTIgYXJlIHByb3ZpZGVkIGZvciBhcHBsaWNhdGlvbnMgb3RoZXIgdGhhbiBkaWZmZXJlbnRpYWwgdGVzdGluZy4qKiBGb3IgZGlmZmVyZW50aWFsIHRlc3Rpbmcgd2UgcmVjb21tZW5kIHRoZSBERVNlcSBmdW5jdGlvbiBhcHBsaWVkIHRvIHJhdyBjb3VudHMsIGFzIGRlc2NyaWJlZCBsYXRlciBpbiB0aGlzIHdvcmtmbG93LCB3aGljaCBhbHNvIHRha2VzIGludG8gYWNjb3VudCB0aGUgZGVwZW5kZW5jZSBvZiB0aGUgdmFyaWFuY2Ugb2YgY291bnRzIG9uIHRoZSBtZWFuIHZhbHVlIGR1cmluZyB0aGUgZGlzcGVyc2lvbiBlc3RpbWF0aW9uIHN0ZXAuIFRoZSBmdW5jdGlvbiBybG9nIHJldHVybnMgYW4gb2JqZWN0IGJhc2VkIG9uIHRoZSBTdW1tYXJpemVkRXhwZXJpbWVudCBjbGFzcyB0aGF0IGNvbnRhaW5zIHRoZSBybG9nLXRyYW5zZm9ybWVkIHZhbHVlcyBpbiBpdHMgYXNzYXkgc2xvdC4gaHR0cDovL3d3dy5iaW9jb25kdWN0b3Iub3JnL2hlbHAvd29ya2Zsb3dzL3JuYXNlcUdlbmUvI3RoZS1kZXNlcWRhdGFzZXQtb2JqZWN0LXNhbXBsZS1pbmZvcm1hdGlvbi1hbmQtdGhlLWRlc2lnbi1mb3JtdWxhCgoKcmxkIDwtIHZzdChkZHMsIGJsaW5kID0gRkFMU0UsZml0VHlwZT0nbG9jYWwnKQpzYW1wbGVEaXN0cyA8LSBkaXN0KHQoYXNzYXkocmxkKSkpCmRmIDwtIGFzLmRhdGEuZnJhbWUoY29sRGF0YShkZHMpWyxjKCJwaHlzaW9sb2d5IiwiY29uZGl0aW9uIiwiY2xhZGUiKV0pCnNhbXBsZURpc3RNYXRyaXggPC0gYXMubWF0cml4KCBzYW1wbGVEaXN0cyApCmNvbG9ycyA8LSBjb2xvclJhbXBQYWxldHRlKCByZXYoYnJld2VyLnBhbCg5LCAiQmx1ZXMiKSkgKSgyNTUpCnBoZWF0bWFwKHNhbXBsZURpc3RNYXRyaXgsCiAgICAgICAgIGNsdXN0ZXJpbmdfZGlzdGFuY2Vfcm93cyA9IHNhbXBsZURpc3RzLAogICAgICAgICBjbHVzdGVyaW5nX2Rpc3RhbmNlX2NvbHMgPSBzYW1wbGVEaXN0cywKICAgICAgICAgY29sID0gY29sb3JzLCBhbm5vdGF0aW9uID0gZGYsIHNob3dfcm93bmFtZXM9RikKCmBgYAoKIyMjIEluZGl2aWR1YWxzIGJ5IFRvcCA1MDAgZ2VuZXMgaGVhdG1hcAoKSGVyZSB3ZSdyZSB1c2luZyB0aGUgc2FtZSB0cmFuc2Zvcm1lZCBjb3VudHMgdG8gbG9vayBhdCBvdmVyYWxsIGV4cHJlc3Npb24sIGhvd2V2ZXIgSSd2ZSBmaWx0ZXJlZCBvdXQgYWxsIGJ1dCB0aGUgdG9wIDUwMCBtb3N0IGhpZ2hseSBleHByZXNzZWQgZ2VuZXMgKG9uIGF2ZXJhZ2UsIGFjcm9zcyBhbGwgaW5kaXZpZHVhbHMpLiBIZXJlLCBJJ20gb25seSBjbHVzdGVyaW5nIGJ5IGluZGl2aWR1YWxzIG9uIHRoZSB4LWF4aXMsIHdoZXJlIHRoZSB4LWF4aXMgaXMgaW5kaXZpZHVhbHMsIGJ1dCB0aGUgeS1heGlzIGlzIHRyYW5zY3JpcHRzLiBIZXJlLCB3ZSBjYW4gc2VlIHRoYXQgaW4gdGhlIDUwMCBtb3N0IGV4cHJlc3NlZCBnZW5lcywgdGhlcmUgYXJlIHZlcnkgZmV3IHRoYXQgaGF2ZSBoaWdobHkgdmFyeWluZyBleHByZXNzaW9uIGFjcm9zcyBzYW1wbGVzLiBIb3dldmVyLCBpbiB0aGVzZSA1MDAgZ2VuZXMsIHdlIGNhbiBiZXR0ZXIgY2x1c3RlciBub24tY2FubmliYWxzIHZzIGNhbm5pYmFscy4gVGhlcmUgaXMgc3RpbGwgcHJldHR5IGdvb2QgY2x1c3RlcmluZyBvZiBmYW1pbGllcyB3aXRoaW4gZmVlZGluZyBzdHJhdGVneS4gCgoKYGBge3IgTWluaVBsYWluR2VuZUhlYXRtYXAsIGVjaG89RkFMU0UsIGZpZy5rZWVwPSJsYXN0IiwgZmlnLndpZHRoPTExLCBmaWcucGF0aD0nZmlndXJlcy8nLCBkZXY9YygncG5nJywgJ3BkZicpfQoKc2VsZWN0MTAwIDwtIG9yZGVyKHJvd01lYW5zKGNvdW50cyhkZHMsbm9ybWFsaXplZD1UUlVFKSksZGVjcmVhc2luZz1UUlVFKVsxOjEwMF0KCnBoZWF0bWFwKGFzc2F5KHJsZClbc2VsZWN0MTAwLF0sIHNob3dfcm93bmFtZXM9VCxjbHVzdGVyaW5nX2Rpc3RhbmNlX3Jvd3MgPSBzYW1wbGVEaXN0cywKICAgICAgICAgY2x1c3RlcmluZ19kaXN0YW5jZV9jb2xzID0gc2FtcGxlRGlzdHMsIGFubm90YXRpb25fY29sPWRmKQoKCmBgYAoKIyMjIEluZGl2aWR1YWxzIGNsdXN0ZXJlZCBieSB0b3AgNTAwIGdlbmUgZXhwcmVzc2lvbgoKVGhpcyBwbG90IGlzIGFuYWxvZ291cyB0byB0aGUgZmlyc3QgaGVhdG1hcCwgaW4gdGhhdCBJJ20gbm93IHNob3dpbmcgYSBjb3JyZWxhdGlvbiBtYXRyaXgsIGhvd2V2ZXIgdGhpcyBpcyB1c2luZyBqdXN0IHRoZSB0b3AgNTAwIG1vc3QgZXhwcmVzc2VkIGdlbmVzIHJhdGhlciB0aGFuIGFsbCBvZiB0aGVtLiBDbHVzdGVyaW5nIHdpdGggdGhlIHRvcCA1MDAgZ2VuZXMgaXMgZ2l2aW5nIHVzIHRocmVlIGJpZyBleHByZXNzaW9uIGdyb3VwczogY2FubmliYWxzLCBub24tY2FubmliYWxzIGFuZCBhIG1peC4KCmBgYHtyIE1pbmlQbGFpbkhlYXRtYXAsIGVjaG89RkFMU0UsIGZpZy5rZWVwPSJsYXN0IiwgZmlnLndpZHRoPTExLCBmaWcucGF0aD0nZmlndXJlcy8nLCBkZXY9YygncG5nJywgJ3BkZicpfQoKc2VsZWN0MTAwIDwtIG9yZGVyKHJvd01lYW5zKGNvdW50cyhkZHMsbm9ybWFsaXplZD1UUlVFKSksZGVjcmVhc2luZz1UUlVFKVsxOjEwMF0KCnNhbXBsZURpc3RzIDwtIGRpc3QodChhc3NheShybGQpW3NlbGVjdDEwMCxdKSkKc2FtcGxlRGlzdE1hdHJpeCA8LSBhcy5tYXRyaXgoIHNhbXBsZURpc3RzICkKCnBoZWF0bWFwKHNhbXBsZURpc3RNYXRyaXgsIHNob3dfcm93bmFtZXM9VCxjbHVzdGVyaW5nX2Rpc3RhbmNlX3Jvd3MgPSBzYW1wbGVEaXN0cywKICAgICAgICAgY2x1c3RlcmluZ19kaXN0YW5jZV9jb2xzID0gc2FtcGxlRGlzdHMsIGFubm90YXRpb25fY29sPWRmKQoKCmBgYAoKIyMjIFBDQSBmb3Igb3ZlcmFsbCBleHByZXNzaW9uCgpIZXJlLCBpbnN0ZWFkIG9mIGxvb2tpbmcgYXQgY29ycmVsYXRpb25zLCB3ZSdyZSBkb2luZyBhIFBDQS4gVGhpcyB0YWtlcyB0aGUgZW50aXJlICh0cmFuc2Zvcm1lZCkgY291bnQgdGFibGUgYW5kIHJvdGF0ZXMgaXQgdG8gZmluZCB0aGUgc2V0IG9mIG9ydGhhZ29uYWwgYXhlcyB3aXRoIHRoZSBtb3N0IHZhcmlhdGlvbi4gSGVyZSBJJ20gYWx3YXlzIHBsb3R0aW5nIFBDMSB2cyBQQzIgKHRoZSBtb3N0IHZhcmlhYmxlIGFuZCBzZWNvbmQgbW9zdCB2YXJpYWJsZSBheGlzKS4gSSdtIGNvbG9yaW5nIHBvaW50cyBieSBlaXRoZXIgZmFtaWx5LCBmZWVkaW5nIHN0cmF0ZWd5LCBvciBib3RoLiBTaW5jZSBQQ0EgbG9va3MgZm9yIHRoZSBheGlzIGluIHRoZSBkYXRhIHdpdGggdGhlIG1vc3QgdmFyaWF0aW9uLCB3aGF0IHRoaXMgd2lsbCBkbyBpcyBwdXNoIGRpcy1zaW1pbGFyIHNhbXBsZXMgYXdheSBmcm9tIGVhY2ggb3RoZXIgaW4gdGhlIHBsb3QuIEluIGVmZmVjdCwgd2UgY2FuIHNlZSB3aGV0aGVyIHRoZXJlIGFyZSBhbHJlYWR5IGNsdXN0ZXJzIGluIHRoZSBkYXRhIGZyb20gdmFyaWFibGVzIHRoYXQgd2UncmUgKm5vdCogaW50ZXJlc3RlZCBpbiBhbmQgd2FudCB0byBtb2RlbCAqb3V0Ki4gCgpJbiB0aGVzZSBwbG90cywgZm9yIGluc3RhbmNlLCB5b3UgY2FuIHNlZSBvbiB0aGUgdG9wIGxlZnQgdGhhdCB0aGUgTWMgc2FtcGxlcyBhcmUgcHJldHR5IGRpZmZlcmVudCBmcm9tIGFsbCB0aGUgb3RoZXJzLCBhbmQgdGhhdCBmYW1pbHkgZWZmZWN0IG1pZ2h0IGJlIHBhcnQgb2Ygd2h5IHdlJ3JlIGdldHRpbmcgdGhyZWUgY2x1c3RlcnMgaW4gdGhlIGxhc3QgaGVhdG1hcC4gSWYgd2UgZG9uJ3QgYWNjb3VudCBmb3IgZmFtaWx5IGluIHRoZSBERVNlcSBtb2RlbCwgd2UnbGwgcHJvYmFibHkgZ2V0IHRoZSB3cm9uZyBnZW5lcy4gCgpJbiB0aGUgdG9wIHJpZ2h0IHBsb3QsIHlvdSBjYW4gc2VlIHRoYXQgbm9uLWNhbm5pYmFscyBhbmQgY2FubmliYWxzIGFjdHVhbGx5IGFyZSBwcmV0dHkgZWFzaWx5IGRpc3Rpbmd1aXNoYWJsZSBqdXN0IGJ5IG92ZXJhbGwgZ2VuZSBleHByZXNzaW9uLCB3aGljaCBpcyBnb29kLiBPbmNlIHdlIGFjY291bnQgZm9yIGZhbWlseSwgd2Ugc2hvdWxkIGhhdmUgYSBmYWlybHkgcmVsaWFibGUgZ2VuZSBsaXN0LiAKCkhvd2V2ZXIsIGlmIHRoZXJlIGFyZSBvdGhlciBtZXRhLWRhdGEgZmFjdG9ycyB0aGF0IGRpZmZlciBiZXR3ZWVuIHNhbXBsZXMgd2Ugc2hvdWxkIGFkZCB0aGVtIGludG8gdGhpcyBwbG90IGFuZCBjaGVjayBmb3IgdGhvc2UgKmJlZm9yZSogZ29pbmcgZm9yd2FyZC4gVGhpcyB3b3VsZCBiZSB0aGluZ3MgbGlrZSBiYXRjaCBlZmZlY3RzLCBsYW5lIGVmZmVjdHMsIHNhbXBsZSBleHRyYWN0aW9uIGRpZmZlcmVuY2VzLCBldGMuCgoKYGBge3IgcGxhaW5QQ0EsIGZpZy5rZWVwPSJsYXN0IiwgZmlnLndpZHRoPTExLCBmaWcucGF0aD0nZmlndXJlcy8nLCBkZXY9YygncG5nJywgJ3BkZicpfQoKCmNvd3Bsb3Q6OnBsb3RfZ3JpZCggcGxvdFBDQShybGQsIGludGdyb3VwPSJjb25kaXRpb24iKSwKICAgICAgICAgICAgICAgICAgICBwbG90UENBKHJsZCwgaW50Z3JvdXA9InBoeXNpb2xvZ3kiKSwKICAgICAgICAgICAgICAgICAgICBwbG90UENBKHJsZCwgaW50Z3JvdXA9ImNsYWRlIiksCiAgICAgICAgICAgICAgICAgICAgcGxvdFBDQShybGQsIGludGdyb3VwPWMoImNsYWRlIiwicGh5c2lvbG9neSIpKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgYWxpZ249ImMiLCBuY29sPTIpCgpgYGAKCg==